﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using PPT = Microsoft.Office.Interop.PowerPoint;
using Office = Microsoft.Office.Core;

namespace An_Im.Tool
{
    public static class StringHelper
    {
        public static string ToPrefix(this string str)
        {
            if (str.Length == 0)
                return "\'";
            else if (str[0] == 'x')
                return "\'";
            else return string.Empty;
        }

        public static string ToAppearPrefix(this string str)
        {
            PPT.MsoAnimEffect enumIndex = (PPT.MsoAnimEffect)Enum.Parse(typeof(PPT.MsoAnimEffect), str);
            if ((int)enumIndex == 52 || (int)enumIndex >= 54)
                return "\'";
            else
                return String.Empty;

        }


        public static string ToSmoothPrefix(this string str)
        {
            if (str.Length == 0)
                return "\'";
            else if (str[0] == 'x')
                return "\'";
            else
            {
                Office.MsoTriState enumIndex = (Office.MsoTriState)Enum.Parse(typeof(Office.MsoTriState), str);
                if (enumIndex == Office.MsoTriState.msoFalse)
                    return "\'";
                else
                    return String.Empty;
            }

        }
    }




    public static class VBACreator
    {
        public enum MsoAnimType
        {
            msoAnimTypeMixed = -2,
            msoAnimTypeNone = 0,
            msoAnimTypeMotion = 1,
            msoAnimTypeColor = 2,
            msoAnimTypeScale = 3,
            msoAnimTypeRotation = 4,
            msoAnimTypeProperty = 5,
            msoAnimTypeCommand = 6,
            msoAnimTypeFilter = 7,
            msoAnimTypeSet = 8
        }

        public enum MsoAnimProperty
        {
            msoAnimNone = 0,
            msoAnimX = 1,
            msoAnimY = 2,
            msoAnimWidth = 3,
            msoAnimHeight = 4,
            msoAnimOpacity = 5,
            msoAnimRotation = 6,
            msoAnimColor = 7,
            msoAnimVisibility = 8,
            msoAnimTextFontBold = 100,
            msoAnimTextFontColor = 101,
            msoAnimTextFontEmboss = 102,
            msoAnimTextFontItalic = 103,
            msoAnimTextFontName = 104,
            msoAnimTextFontShadow = 105,
            msoAnimTextFontSize = 106,
            msoAnimTextFontSubscript = 107,
            msoAnimTextFontSuperscript = 108,
            msoAnimTextFontUnderline = 109,
            msoAnimTextFontStrikeThrough = 110,
            msoAnimTextBulletCharacter = 111,
            msoAnimTextBulletFontName = 112,
            msoAnimTextBulletNumber = 113,
            msoAnimTextBulletColor = 114,
            msoAnimTextBulletRelativeSize = 115,
            msoAnimTextBulletStyle = 116,
            msoAnimTextBulletType = 117,
            msoAnimShapePictureContrast = 1000,
            msoAnimShapePictureBrightness = 1001,
            msoAnimShapePictureGamma = 1002,
            msoAnimShapePictureGrayscale = 1003,
            msoAnimShapeFillOn = 1004,
            msoAnimShapeFillColor = 1005,
            msoAnimShapeFillOpacity = 1006,
            msoAnimShapeFillBackColor = 1007,
            msoAnimShapeLineOn = 1008,
            msoAnimShapeLineColor = 1009,
            msoAnimShapeShadowOn = 1010,
            msoAnimShapeShadowType = 1011,
            msoAnimShapeShadowColor = 1012,
            msoAnimShapeShadowOpacity = 1013,
            msoAnimShapeShadowOffsetX = 1014,
            msoAnimShapeShadowOffsetY = 1015
        }

        static Dictionary<string, string> typedic1;
        static Dictionary<string, string> typedic2;
        static Dictionary<string, string> propdic1;
        static Dictionary<string, string> propdic2;
        static HashSet<string> emphdic; // 强调动画名

        static VBACreator()
        {
            typedic1 = new Dictionary<string, string>();
            typedic2 = new Dictionary<string, string>();
            propdic1 = new Dictionary<string, string>();
            propdic2 = new Dictionary<string, string>();
            emphdic = new HashSet<string>();

            AddTypeDicRecord(MsoAnimType.msoAnimTypeSet, "设置");
            AddTypeDicRecord(MsoAnimType.msoAnimTypeProperty, "属性");
            AddTypeDicRecord(MsoAnimType.msoAnimTypeColor, "颜色");
            AddTypeDicRecord(MsoAnimType.msoAnimTypeScale, "比例");
            AddTypeDicRecord(MsoAnimType.msoAnimTypeRotation, "旋转");
            AddTypeDicRecord(MsoAnimType.msoAnimTypeFilter, "滤镜");
            AddTypeDicRecord(MsoAnimType.msoAnimTypeMotion, "移动");

            AddPropDicRecord(MsoAnimProperty.msoAnimX, "X");
            AddPropDicRecord(MsoAnimProperty.msoAnimY, "Y");
            AddPropDicRecord(MsoAnimProperty.msoAnimVisibility, "可见性");
            AddPropDicRecord(MsoAnimProperty.msoAnimWidth, "宽度");
            AddPropDicRecord(MsoAnimProperty.msoAnimHeight, "高度");
            AddPropDicRecord(MsoAnimProperty.msoAnimColor, "颜色");
            AddPropDicRecord(MsoAnimProperty.msoAnimOpacity, "透明度");
            AddPropDicRecord(MsoAnimProperty.msoAnimRotation, "角度");

            emphdic.Add("msoAnimEffectSpin");
            emphdic.Add("msoAnimEffect");

        }

        public static void AnalyzeDataBase(string path)
        {
            var xmldoc = new XmlDocument();
            xmldoc.Load(path);
            var fileStream = new FileStream(Path.Combine(Environment.CurrentDirectory, "AnIm动画库.bas"), FileMode.Create);

            foreach (var animEffect in xmldoc["动画数据"]["原生列表"].OfType<XmlElement>())
            {
                var sb = CreateArtificialVBACode(animEffect);
                var bytes = Encoding.Default.GetBytes(sb.ToString());
                fileStream.Write(bytes, 0, bytes.Length);
            }

            foreach (var animEffect in xmldoc["动画数据"]["人工列表"].OfType<XmlElement>())
            {
                var sb = CreateArtificialVBACode(animEffect);
                var bytes = Encoding.Default.GetBytes(sb.ToString());
                fileStream.Write(bytes, 0, bytes.Length);
            }
            fileStream.Close();
        }

        static string GetRepeat(string value)
        {
            if (value == "forever") return "999";
            else return value;
        }

        static void AddTypeDicRecord(MsoAnimType animType, string name)
        {
            typedic1.Add(Enum.GetName(typeof(MsoAnimType), animType), name);
            typedic2.Add(name, Enum.GetName(typeof(MsoAnimType), animType));
        }

        static void AddPropDicRecord(MsoAnimProperty animType, string name)
        {
            propdic1.Add(Enum.GetName(typeof(MsoAnimProperty), animType), name);
            propdic2.Add(name, Enum.GetName(typeof(MsoAnimProperty), animType));
        }

        public static string CreateArtificialVBACode(string xmlcode)
        {
            var xmldoc = new XmlDocument();
            xmldoc.LoadXml(xmlcode);
            return CreateArtificialVBACode(xmldoc["动画效果"]);
        }

        public static string CreateNativeVBACode(string xmlcode)
        {
            var xmldoc = new XmlDocument();
            xmldoc.LoadXml(xmlcode);
            return CreateNativeVBACode(xmldoc["原生动画效果"]);
        }

        public static string CreateArtificialVBACode(string xmlcode, string name)
        {
            var xmldoc = new XmlDocument();
            xmldoc.LoadXml(xmlcode);
            return CreateArtificialVBACode(xmldoc["动画效果"], name);
        }

        public static string CreateNativeVBACode(string xmlcode, string name)
        {
            var xmldoc = new XmlDocument();
            xmldoc.LoadXml(xmlcode);
            return CreateNativeVBACode(xmldoc["原生动画效果"], name);
        }

        public static PPT.MsoAnimEffect StringToPPTAnimType(string str)
        {
            PPT.MsoAnimEffect enumIndex = (PPT.MsoAnimEffect)Enum.Parse(typeof(PPT.MsoAnimEffect), str);
            return enumIndex;
        }

        public static string GetValidVBASubName(string name)
        {
            if (name.StartsWith("PA-"))
                name = name.Substring(3);
            name = name.Replace('-', '_');
            return name.Replace(' ', '_').TrimStart('_');
        }


        public static string CreateArtificialVBACode(XmlElement animEffect)
        {
            StringBuilder sb = new StringBuilder();
            var 名称 = GetValidVBASubName(animEffect.GetAttribute("名称"));
            var 文本模式 = animEffect.GetAttribute("文本模式");
            var 时长 = animEffect.GetAttribute("时长");
            var 延迟 = animEffect.GetAttribute("延迟");
            var 重复 = GetRepeat(animEffect.GetAttribute("重复"));
            var 平滑 = animEffect.GetAttribute("平滑").Split(',');
            var 平滑1 = 平滑[0];
            var 平滑2 = 平滑[1];
            var 弹跳 = animEffect.GetAttribute("弹跳");
            var 加速 = animEffect.GetAttribute("加速");
            var 减速 = animEffect.GetAttribute("减速");
            var 弹跳速度 = animEffect.GetAttribute("弹跳速度");
            var 自动返回 = animEffect.GetAttribute("自动返回");
            sb.AppendLine("Sub " + 名称 + "()");
            sb.AppendLine("    Dim shp As Shape");
            sb.AppendLine("    Dim shprange As ShapeRange");
            sb.AppendLine("    Dim sld As Slide");
            sb.AppendLine("    Dim eff As Effect");
            sb.AppendLine("    Dim bhv As AnimationBehavior");
            sb.AppendLine("    Dim pt As AnimationPoint");
            sb.AppendLine("    Set shprange = Application.ActiveWindow.Selection.ShapeRange");
            sb.AppendLine("    Set sld = shprange.Parent");

            sb.AppendLine("    For Each shp In shprange");
            // sb.AppendLine("        shp.AnimationSettings.TextUnitEffect = " + 文本模式);
            sb.AppendLine("        Set eff = sld.TimeLine.MainSequence.AddEffect(shp, msoAnimEffectCustom, , msoAnimTriggerWithPrevious)");

            sb.AppendLine(时长.ToPrefix() + "        eff.Timing.Duration = " + 时长);
            sb.AppendLine(延迟.ToPrefix() + "        eff.Timing.TriggerDelayTime = " + 延迟);
            sb.AppendLine(重复.ToPrefix() + "        eff.Timing.RepeatCount = " + 重复);

            sb.AppendLine(平滑1.ToPrefix() + "        eff.Timing.SmoothStart = " + 平滑1);
            sb.AppendLine(平滑2.ToPrefix() + "        eff.Timing.SmoothEnd = " + 平滑2);
            sb.AppendLine(弹跳.ToPrefix() + "        eff.Timing.BounceEnd = " + 弹跳);

            sb.AppendLine(平滑1.ToSmoothPrefix() + "        eff.Timing.Accelerate = " + 加速);
            sb.AppendLine(平滑2.ToSmoothPrefix() + "        eff.Timing.Decelerate = " + 减速);
            sb.AppendLine(弹跳.ToSmoothPrefix() + "        eff.Timing.BounceEndIntensity = " + 弹跳速度);

            sb.AppendLine(自动返回.ToPrefix() + "        eff.Timing.AutoReverse = " + 自动返回);

            foreach (var behavior in animEffect.OfType<XmlElement>())
            {
                var b名称 = behavior.Name;
                var b时长 = behavior.GetAttribute("时长");
                var b延迟 = behavior.GetAttribute("延迟");
                var b重复 = GetRepeat(behavior.GetAttribute("重复"));
                var b平滑 = behavior.GetAttribute("平滑").Split(',');
                var b平滑1 = b平滑[0];
                var b平滑2 = b平滑[1];
                var b弹跳 = behavior.GetAttribute("弹跳");
                var b加速 = behavior.GetAttribute("加速");
                var b减速 = behavior.GetAttribute("减速");
                var b弹跳速度 = behavior.GetAttribute("弹跳速度");
                var b自动返回 = behavior.GetAttribute("自动返回");
                sb.AppendLine("\'        =======================================================");
                sb.AppendLine("        Set bhv = eff.Behaviors.Add(" + typedic2[b名称] + ")");
                sb.AppendLine(b时长.ToPrefix() + "        bhv.Timing.Duration = " + b时长);
                sb.AppendLine(b延迟.ToPrefix() + "        bhv.Timing.TriggerDelayTime = " + b延迟);
                sb.AppendLine(b重复.ToPrefix() + "        bhv.Timing.RepeatCount = " + b重复);

                sb.AppendLine(b平滑1.ToPrefix() + "        bhv.Timing.SmoothStart = " + b平滑1);
                sb.AppendLine(b平滑2.ToPrefix() + "        bhv.Timing.SmoothEnd = " + b平滑2);
                sb.AppendLine(b弹跳.ToPrefix() + "        bhv.Timing.BounceEnd = " + b弹跳);

                sb.AppendLine(b平滑1.ToSmoothPrefix() + "        bhv.Timing.Accelerate = " + b加速);
                sb.AppendLine(b平滑2.ToSmoothPrefix() + "        bhv.Timing.Decelerate = " + b减速);
                sb.AppendLine(b弹跳.ToSmoothPrefix() + "        bhv.Timing.BounceEndIntensity = " + b弹跳速度);

                sb.AppendLine(b自动返回.ToPrefix() + "        bhv.Timing.AutoReverse = " + b自动返回);
                sb.AppendLine();
                //sb.AppendLine("        bhv.Timing.Duration = " + b时长);
                //sb.AppendLine("        bhv.Timing.TriggerDelayTime = " + b延迟);
                //sb.AppendLine("        bhv.Timing.RepeatCount = " + b重复);

                switch (b名称)
                {
                    case "设置":
                        var set属性类型 = behavior.GetAttribute("属性类型");
                        var set属性值 = behavior.GetAttribute("属性值");
                        sb.AppendLine(set属性类型.ToPrefix() + "        bhv.SetEffect.Property = " + propdic2[set属性类型]);
                        sb.AppendLine(set属性值.ToPrefix() + "        bhv.SetEffect.To = " + set属性值);

                        break;
                    case "属性":
                        var prop属性类型 = behavior.GetAttribute("属性类型");
                        var prop属性值 = behavior.GetAttribute("属性值");
                        sb.AppendLine(prop属性类型.ToPrefix() + "        bhv.PropertyEffect.Property = " + propdic2[prop属性类型]);
                        sb.AppendLine(prop属性值.ToPrefix() + "        bhv.PropertyEffect.To = " + prop属性值);
                        foreach (var point in behavior.OfType<XmlElement>())
                        {
                            var pt时间 = point.GetAttribute("时间");
                            var pt值 = point.GetAttribute("值");
                            var pt表达式 = point.GetAttribute("表达式");
                            sb.AppendLine("        Set pt = bhv.PropertyEffect.Points.Add");
                            sb.AppendLine("        pt.Time = 0" + pt时间 + ": pt.Value = \"" + pt值 + "\": pt.Formula = \"" + pt表达式 + "\"");

                        }
                        break;
                    case "颜色":
                        var clr起点 = behavior.GetAttribute("起点");
                        var clr终点 = behavior.GetAttribute("终点");
                        var clr变化 = behavior.GetAttribute("变化");
                        sb.AppendLine(clr起点.ToPrefix() + "        bhv.ColorEffect.From.RGB = " + clr起点);
                        sb.AppendLine(clr终点.ToPrefix() + "        bhv.ColorEffect.To.RGB = " + clr终点);
                        //sb.AppendLine("        bhv.ColorEffect.By.RGB = " + clr变化);
                        break;
                    case "比例":
                        var sc起点 = behavior.GetAttribute("起点").Split(',');
                        var sc终点 = behavior.GetAttribute("终点").Split(',');
                        var sc变化 = behavior.GetAttribute("变化").Split(',');
                        sb.AppendLine(sc起点[0].ToPrefix() + "        bhv.ScaleEffect.FromX = " + sc起点[0]);
                        sb.AppendLine(sc起点[1].ToPrefix() + "        bhv.ScaleEffect.FromY = " + sc起点[1]);
                        sb.AppendLine(sc终点[0].ToPrefix() + "        bhv.ScaleEffect.ToX = " + sc终点[0]);
                        sb.AppendLine(sc终点[1].ToPrefix() + "        bhv.ScaleEffect.ToY = " + sc终点[1]);
                        //sb.AppendLine("        bhv.ScaleEffect.ByX = " + sc变化[0]);
                        //sb.AppendLine("        bhv.ScaleEffect.ByY = " + sc变化[1]);
                        break;
                    case "旋转":
                        var rot起点 = behavior.GetAttribute("起点");
                        var rot终点 = behavior.GetAttribute("终点");
                        var rot变化 = behavior.GetAttribute("变化");
                        sb.AppendLine(rot起点.ToPrefix() + "        bhv.RotationEffect.From = " + rot起点);
                        sb.AppendLine(rot终点.ToPrefix() + "        bhv.RotationEffect.To = " + rot终点);
                        //sb.AppendLine("        bhv.RotationEffect.From = " + "0");
                        //sb.AppendLine("        bhv.RotationEffect.To = " + rot变化);
                        //sb.AppendLine("        bhv.RotationEffect.By = " + rot变化);
                        break;
                    case "滤镜":
                        var ft主滤镜 = behavior.GetAttribute("主滤镜");
                        var ft子滤镜 = behavior.GetAttribute("子滤镜");
                        var ft反转 = behavior.GetAttribute("反转");
                        sb.AppendLine(ft反转.ToPrefix() + "        bhv.FilterEffect.Reveal = " + ft反转);
                        sb.AppendLine(ft主滤镜.ToPrefix() + "         bhv.FilterEffect.Type = " + ft主滤镜);
                        if (ft子滤镜 != "none")
                            sb.AppendLine("         bhv.FilterEffect.Subtype = " + ft子滤镜);
                        break;
                    case "移动":
                        var mo起点 = behavior.GetAttribute("起点").Split(',');
                        var mo终点 = behavior.GetAttribute("终点").Split(',');
                        var mo变化 = behavior.GetAttribute("变化").Split(',');
                        var mo路径 = behavior.GetAttribute("路径");
                        sb.AppendLine(mo起点[0].ToPrefix() + "        bhv.MotionEffect.FromX = " + mo起点[0]);
                        sb.AppendLine(mo起点[1].ToPrefix() + "        bhv.MotionEffect.FromY = " + mo起点[1]);
                        sb.AppendLine(mo终点[0].ToPrefix() + "        bhv.MotionEffect.ToX = " + mo终点[0]);
                        sb.AppendLine(mo终点[1].ToPrefix() + "        bhv.MotionEffect.ToY = " + mo终点[1]);
                        //sb.AppendLine("        bhv.MotionEffect.ByX = " + mo变化[0]);
                        //sb.AppendLine("        bhv.MotionEffect.ByY = " + mo变化[1]);
                        sb.AppendLine(mo路径.ToPrefix() + "        bhv.MotionEffect.Path = \"" + mo路径 + "\"");
                        sb.AppendLine("    sld.TimeLine.MainSequence.ConvertToTextUnitEffect eff, " + 文本模式);
                        break;
                    default:
                        break;
                }

            }
            sb.AppendLine("\'        =======================================================");
            sb.AppendLine("        eff.Behaviors(1).Delete");
            sb.AppendLine("    sld.TimeLine.MainSequence.ConvertToTextUnitEffect eff, " + 文本模式);
            sb.AppendLine("    Next");

            sb.AppendLine("End Sub");
            sb.AppendLine();
            return sb.ToString();
        }

        public static string CreateNativeVBACode(XmlElement animEffect)
        {
            StringBuilder sb = new StringBuilder();

            var 名称 = GetValidVBASubName(animEffect.GetAttribute("名称"));
            var 文本模式 = animEffect.GetAttribute("文本模式");
            var 时长 = animEffect.GetAttribute("时长");
            var 延迟 = animEffect.GetAttribute("延迟");
            var 重复 = GetRepeat(animEffect.GetAttribute("重复"));
            var 平滑 = animEffect.GetAttribute("平滑").Split(',');
            var 平滑1 = 平滑[0];
            var 平滑2 = 平滑[1];
            var 弹跳 = animEffect.GetAttribute("弹跳");
            var 加速 = animEffect.GetAttribute("加速");
            var 减速 = animEffect.GetAttribute("减速");
            var 弹跳速度 = animEffect.GetAttribute("弹跳速度");
            var 自动返回 = animEffect.GetAttribute("自动返回");
            var 类型 = animEffect.GetAttribute("类型");
            var 退出 = animEffect.GetAttribute("退出");
            var 参数列表 = animEffect.GetAttribute("参数列表").Split(',');
            var pptAnimType = StringToPPTAnimType(类型);
            sb.AppendLine("Sub " + 名称 + "()");
            sb.AppendLine("    Dim shp As Shape");
            sb.AppendLine("    Dim shprange As ShapeRange");
            sb.AppendLine("    Dim sld As Slide");
            sb.AppendLine("    Dim eff As Effect");
            sb.AppendLine("    Dim bhv As AnimationBehavior");
            sb.AppendLine("    Dim pt As AnimationPoint");
            sb.AppendLine("    Set shprange = Application.ActiveWindow.Selection.ShapeRange");
            sb.AppendLine("    Set sld = shprange.Parent");

            sb.AppendLine("    For Each shp In shprange");
            //sb.AppendLine("        shp.AnimationSettings.TextUnitEffect = "+ 文本模式);

            sb.AppendLine("        Set eff = sld.TimeLine.MainSequence.AddEffect(shp, " + 类型 + ", , msoAnimTriggerWithPrevious)");

            if (!emphdic.Contains(类型))
                sb.AppendLine(类型.ToAppearPrefix() + "        eff.Exit = " + 退出);

            sb.AppendLine(时长.ToPrefix() + "        eff.Timing.Duration = " + 时长);
            sb.AppendLine(延迟.ToPrefix() + "        eff.Timing.TriggerDelayTime = " + 延迟);
            sb.AppendLine(重复.ToPrefix() + "        eff.Timing.RepeatCount = " + 重复);

            sb.AppendLine(平滑1.ToPrefix() + "        eff.Timing.SmoothStart = " + 平滑1);
            sb.AppendLine(平滑2.ToPrefix() + "        eff.Timing.SmoothEnd = " + 平滑2);
            sb.AppendLine(弹跳.ToPrefix() + "        eff.Timing.BounceEnd = " + 弹跳);

            sb.AppendLine(平滑1.ToSmoothPrefix() + "        eff.Timing.Accelerate = " + 加速);
            sb.AppendLine(平滑2.ToSmoothPrefix() + "        eff.Timing.Decelerate = " + 减速);
            sb.AppendLine(弹跳.ToSmoothPrefix() + "        eff.Timing.BounceEndIntensity = " + 弹跳速度);

            sb.AppendLine(自动返回.ToPrefix() + "        eff.Timing.AutoReverse = " + 自动返回);


            if (pptAnimType == PPT.MsoAnimEffect.msoAnimEffectGrowShrink)
            {
                sb.AppendLine(String.Format(Properties.Resources.DetailAnimVBA_Large, 参数列表));
            }
            else if (pptAnimType == PPT.MsoAnimEffect.msoAnimEffectSpin)
            {
                sb.AppendLine(String.Format(Properties.Resources.DetailAnimVBA_Spin, 参数列表));
            }
            else if ((int)pptAnimType >= (int)PPT.MsoAnimEffect.msoAnimEffectPathCircle)
            {
                sb.AppendLine(String.Format(Properties.Resources.DetailAnimVBA_Path, 参数列表));
            }
            sb.AppendLine("    sld.TimeLine.MainSequence.ConvertToTextUnitEffect eff, " + 文本模式);



            sb.AppendLine("    Next");
            sb.AppendLine("End Sub");
            sb.AppendLine();
            return sb.ToString();
        }

        public static string CreateArtificialVBACode(XmlElement animEffect, string name)
        {
            StringBuilder sb = new StringBuilder();
            var 名称 = GetValidVBASubName(name);
            var 文本模式 = animEffect.GetAttribute("文本模式");
            var 时长 = animEffect.GetAttribute("时长");
            var 延迟 = animEffect.GetAttribute("延迟");
            var 重复 = GetRepeat(animEffect.GetAttribute("重复"));
            var 平滑 = animEffect.GetAttribute("平滑").Split(',');
            var 平滑1 = 平滑[0];
            var 平滑2 = 平滑[1];
            var 弹跳 = animEffect.GetAttribute("弹跳");
            var 加速 = animEffect.GetAttribute("加速");
            var 减速 = animEffect.GetAttribute("减速");
            var 弹跳速度 = animEffect.GetAttribute("弹跳速度");
            var 自动返回 = animEffect.GetAttribute("自动返回");
            sb.AppendLine("Sub " + 名称 + "()");
            sb.AppendLine("    Dim shp As Shape");
            sb.AppendLine("    Dim shprange As ShapeRange");
            sb.AppendLine("    Dim sld As Slide");
            sb.AppendLine("    Dim eff As Effect");
            sb.AppendLine("    Dim bhv As AnimationBehavior");
            sb.AppendLine("    Dim pt As AnimationPoint");
            sb.AppendLine("    Set shprange = Application.ActiveWindow.Selection.ShapeRange");
            sb.AppendLine("    Set sld = shprange.Parent");

            sb.AppendLine("    For Each shp In shprange");
            // sb.AppendLine("        shp.AnimationSettings.TextUnitEffect = " + 文本模式);
            sb.AppendLine("        Set eff = sld.TimeLine.MainSequence.AddEffect(shp, msoAnimEffectCustom, , msoAnimTriggerWithPrevious)");

            sb.AppendLine(时长.ToPrefix() + "        eff.Timing.Duration = " + 时长);
            sb.AppendLine(延迟.ToPrefix() + "        eff.Timing.TriggerDelayTime = " + 延迟);
            sb.AppendLine(重复.ToPrefix() + "        eff.Timing.RepeatCount = " + 重复);

            sb.AppendLine(平滑1.ToPrefix() + "        eff.Timing.SmoothStart = " + 平滑1);
            sb.AppendLine(平滑2.ToPrefix() + "        eff.Timing.SmoothEnd = " + 平滑2);
            sb.AppendLine(弹跳.ToPrefix() + "        eff.Timing.BounceEnd = " + 弹跳);

            sb.AppendLine(平滑1.ToSmoothPrefix() + "        eff.Timing.Accelerate = " + 加速);
            sb.AppendLine(平滑2.ToSmoothPrefix() + "        eff.Timing.Decelerate = " + 减速);
            sb.AppendLine(弹跳.ToSmoothPrefix() + "        eff.Timing.BounceEndIntensity = " + 弹跳速度);

            sb.AppendLine(自动返回.ToPrefix() + "        eff.Timing.AutoReverse = " + 自动返回);

            foreach (var behavior in animEffect.OfType<XmlElement>())
            {
                var b名称 = behavior.Name;
                var b时长 = behavior.GetAttribute("时长");
                var b延迟 = behavior.GetAttribute("延迟");
                var b重复 = GetRepeat(behavior.GetAttribute("重复"));
                var b平滑 = behavior.GetAttribute("平滑").Split(',');
                var b平滑1 = b平滑[0];
                var b平滑2 = b平滑[1];
                var b弹跳 = behavior.GetAttribute("弹跳");
                var b加速 = behavior.GetAttribute("加速");
                var b减速 = behavior.GetAttribute("减速");
                var b弹跳速度 = behavior.GetAttribute("弹跳速度");
                var b自动返回 = behavior.GetAttribute("自动返回");
                sb.AppendLine("\'        =======================================================");
                sb.AppendLine("        Set bhv = eff.Behaviors.Add(" + typedic2[b名称] + ")");
                sb.AppendLine(b时长.ToPrefix() + "        bhv.Timing.Duration = " + b时长);
                sb.AppendLine(b延迟.ToPrefix() + "        bhv.Timing.TriggerDelayTime = " + b延迟);
                sb.AppendLine(b重复.ToPrefix() + "        bhv.Timing.RepeatCount = " + b重复);

                sb.AppendLine(b平滑1.ToPrefix() + "        bhv.Timing.SmoothStart = " + b平滑1);
                sb.AppendLine(b平滑2.ToPrefix() + "        bhv.Timing.SmoothEnd = " + b平滑2);
                sb.AppendLine(b弹跳.ToPrefix() + "        bhv.Timing.BounceEnd = " + b弹跳);

                sb.AppendLine(b平滑1.ToSmoothPrefix() + "        bhv.Timing.Accelerate = " + b加速);
                sb.AppendLine(b平滑2.ToSmoothPrefix() + "        bhv.Timing.Decelerate = " + b减速);
                sb.AppendLine(b弹跳.ToSmoothPrefix() + "        bhv.Timing.BounceEndIntensity = " + b弹跳速度);

                sb.AppendLine(b自动返回.ToPrefix() + "        bhv.Timing.AutoReverse = " + b自动返回);
                sb.AppendLine();
                //sb.AppendLine("        bhv.Timing.Duration = " + b时长);
                //sb.AppendLine("        bhv.Timing.TriggerDelayTime = " + b延迟);
                //sb.AppendLine("        bhv.Timing.RepeatCount = " + b重复);

                switch (b名称)
                {
                    case "设置":
                        var set属性类型 = behavior.GetAttribute("属性类型");
                        var set属性值 = behavior.GetAttribute("属性值");
                        sb.AppendLine(set属性类型.ToPrefix() + "        bhv.SetEffect.Property = " + propdic2[set属性类型]);
                        sb.AppendLine(set属性值.ToPrefix() + "        bhv.SetEffect.To = " + set属性值);

                        break;
                    case "属性":
                        var prop属性类型 = behavior.GetAttribute("属性类型");
                        var prop属性值 = behavior.GetAttribute("属性值");
                        sb.AppendLine(prop属性类型.ToPrefix() + "        bhv.PropertyEffect.Property = " + propdic2[prop属性类型]);
                        sb.AppendLine(prop属性值.ToPrefix() + "        bhv.PropertyEffect.To = " + prop属性值);
                        foreach (var point in behavior.OfType<XmlElement>())
                        {
                            var pt时间 = point.GetAttribute("时间");
                            var pt值 = point.GetAttribute("值");
                            var pt表达式 = point.GetAttribute("表达式");
                            sb.AppendLine("        Set pt = bhv.PropertyEffect.Points.Add");
                            sb.AppendLine("        pt.Time = 0" + pt时间 + ": pt.Value = \"" + pt值 + "\": pt.Formula = \"" + pt表达式 + "\"");

                        }
                        break;
                    case "颜色":
                        var clr起点 = behavior.GetAttribute("起点");
                        var clr终点 = behavior.GetAttribute("终点");
                        var clr变化 = behavior.GetAttribute("变化");
                        sb.AppendLine(clr起点.ToPrefix() + "        bhv.ColorEffect.From.RGB = " + clr起点);
                        sb.AppendLine(clr终点.ToPrefix() + "        bhv.ColorEffect.To.RGB = " + clr终点);
                        //sb.AppendLine("        bhv.ColorEffect.By.RGB = " + clr变化);
                        break;
                    case "比例":
                        var sc起点 = behavior.GetAttribute("起点").Split(',');
                        var sc终点 = behavior.GetAttribute("终点").Split(',');
                        var sc变化 = behavior.GetAttribute("变化").Split(',');
                        sb.AppendLine(sc起点[0].ToPrefix() + "        bhv.ScaleEffect.FromX = " + sc起点[0]);
                        sb.AppendLine(sc起点[1].ToPrefix() + "        bhv.ScaleEffect.FromY = " + sc起点[1]);
                        sb.AppendLine(sc终点[0].ToPrefix() + "        bhv.ScaleEffect.ToX = " + sc终点[0]);
                        sb.AppendLine(sc终点[1].ToPrefix() + "        bhv.ScaleEffect.ToY = " + sc终点[1]);
                        //sb.AppendLine("        bhv.ScaleEffect.ByX = " + sc变化[0]);
                        //sb.AppendLine("        bhv.ScaleEffect.ByY = " + sc变化[1]);
                        break;
                    case "旋转":
                        var rot起点 = behavior.GetAttribute("起点");
                        var rot终点 = behavior.GetAttribute("终点");
                        var rot变化 = behavior.GetAttribute("变化");
                        sb.AppendLine(rot起点.ToPrefix() + "        bhv.RotationEffect.From = " + rot起点);
                        sb.AppendLine(rot终点.ToPrefix() + "        bhv.RotationEffect.To = " + rot终点);
                        //sb.AppendLine("        bhv.RotationEffect.From = " + "0");
                        //sb.AppendLine("        bhv.RotationEffect.To = " + rot变化);
                        //sb.AppendLine("        bhv.RotationEffect.By = " + rot变化);
                        break;
                    case "滤镜":
                        var ft主滤镜 = behavior.GetAttribute("主滤镜");
                        var ft子滤镜 = behavior.GetAttribute("子滤镜");
                        var ft反转 = behavior.GetAttribute("反转");
                        sb.AppendLine(ft反转.ToPrefix() + "        bhv.FilterEffect.Reveal = " + ft反转);
                        sb.AppendLine(ft主滤镜.ToPrefix() + "         bhv.FilterEffect.Type = " + ft主滤镜);
                        if (ft子滤镜 != "none")
                            sb.AppendLine("         bhv.FilterEffect.Subtype = " + ft子滤镜);
                        break;
                    case "移动":
                        var mo起点 = behavior.GetAttribute("起点").Split(',');
                        var mo终点 = behavior.GetAttribute("终点").Split(',');
                        var mo变化 = behavior.GetAttribute("变化").Split(',');
                        var mo路径 = behavior.GetAttribute("路径");
                        sb.AppendLine(mo起点[0].ToPrefix() + "        bhv.MotionEffect.FromX = " + mo起点[0]);
                        sb.AppendLine(mo起点[1].ToPrefix() + "        bhv.MotionEffect.FromY = " + mo起点[1]);
                        sb.AppendLine(mo终点[0].ToPrefix() + "        bhv.MotionEffect.ToX = " + mo终点[0]);
                        sb.AppendLine(mo终点[1].ToPrefix() + "        bhv.MotionEffect.ToY = " + mo终点[1]);
                        //sb.AppendLine("        bhv.MotionEffect.ByX = " + mo变化[0]);
                        //sb.AppendLine("        bhv.MotionEffect.ByY = " + mo变化[1]);
                        sb.AppendLine(mo路径.ToPrefix() + "        bhv.MotionEffect.Path = \"" + mo路径 + "\"");
                        sb.AppendLine("    sld.TimeLine.MainSequence.ConvertToTextUnitEffect eff, " + 文本模式);
                        break;
                    default:
                        break;
                }

            }
            sb.AppendLine("\'        =======================================================");
            sb.AppendLine("        eff.Behaviors(1).Delete");
            sb.AppendLine("    sld.TimeLine.MainSequence.ConvertToTextUnitEffect eff, " + 文本模式);
            sb.AppendLine("    Next");

            sb.AppendLine("End Sub");
            sb.AppendLine();
            return sb.ToString();
        }

        public static string CreateNativeVBACode(XmlElement animEffect, string name)
        {
            StringBuilder sb = new StringBuilder();

            var 名称 = GetValidVBASubName(name);
            var 文本模式 = animEffect.GetAttribute("文本模式");
            var 时长 = animEffect.GetAttribute("时长");
            var 延迟 = animEffect.GetAttribute("延迟");
            var 重复 = GetRepeat(animEffect.GetAttribute("重复"));
            var 平滑 = animEffect.GetAttribute("平滑").Split(',');
            var 平滑1 = 平滑[0];
            var 平滑2 = 平滑[1];
            var 弹跳 = animEffect.GetAttribute("弹跳");
            var 加速 = animEffect.GetAttribute("加速");
            var 减速 = animEffect.GetAttribute("减速");
            var 弹跳速度 = animEffect.GetAttribute("弹跳速度");
            var 自动返回 = animEffect.GetAttribute("自动返回");
            var 类型 = animEffect.GetAttribute("类型");
            var 退出 = animEffect.GetAttribute("退出");
            var 参数列表 = animEffect.GetAttribute("参数列表").Split(',');
            var pptAnimType = StringToPPTAnimType(类型);
            sb.AppendLine("Sub " + 名称 + "()");
            sb.AppendLine("    Dim shp As Shape");
            sb.AppendLine("    Dim shprange As ShapeRange");
            sb.AppendLine("    Dim sld As Slide");
            sb.AppendLine("    Dim eff As Effect");
            sb.AppendLine("    Dim bhv As AnimationBehavior");
            sb.AppendLine("    Dim pt As AnimationPoint");
            sb.AppendLine("    Set shprange = Application.ActiveWindow.Selection.ShapeRange");
            sb.AppendLine("    Set sld = shprange.Parent");

            sb.AppendLine("    For Each shp In shprange");
            //sb.AppendLine("        shp.AnimationSettings.TextUnitEffect = "+ 文本模式);

            sb.AppendLine("        Set eff = sld.TimeLine.MainSequence.AddEffect(shp, " + 类型 + ", , msoAnimTriggerWithPrevious)");

            if (!emphdic.Contains(类型))
                sb.AppendLine(类型.ToAppearPrefix() + "        eff.Exit = " + 退出);

            sb.AppendLine(时长.ToPrefix() + "        eff.Timing.Duration = " + 时长);
            sb.AppendLine(延迟.ToPrefix() + "        eff.Timing.TriggerDelayTime = " + 延迟);
            sb.AppendLine(重复.ToPrefix() + "        eff.Timing.RepeatCount = " + 重复);

            sb.AppendLine(平滑1.ToPrefix() + "        eff.Timing.SmoothStart = " + 平滑1);
            sb.AppendLine(平滑2.ToPrefix() + "        eff.Timing.SmoothEnd = " + 平滑2);
            sb.AppendLine(弹跳.ToPrefix() + "        eff.Timing.BounceEnd = " + 弹跳);

            sb.AppendLine(平滑1.ToSmoothPrefix() + "        eff.Timing.Accelerate = " + 加速);
            sb.AppendLine(平滑2.ToSmoothPrefix() + "        eff.Timing.Decelerate = " + 减速);
            sb.AppendLine(弹跳.ToSmoothPrefix() + "        eff.Timing.BounceEndIntensity = " + 弹跳速度);

            sb.AppendLine(自动返回.ToPrefix() + "        eff.Timing.AutoReverse = " + 自动返回);


            if (pptAnimType == PPT.MsoAnimEffect.msoAnimEffectGrowShrink)
            {
                sb.AppendLine(String.Format(Properties.Resources.DetailAnimVBA_Large, 参数列表));
            }
            else if (pptAnimType == PPT.MsoAnimEffect.msoAnimEffectSpin)
            {
                sb.AppendLine(String.Format(Properties.Resources.DetailAnimVBA_Spin, 参数列表));
            }
            else if ((int)pptAnimType >= (int)PPT.MsoAnimEffect.msoAnimEffectPathCircle)
            {
                sb.AppendLine(String.Format(Properties.Resources.DetailAnimVBA_Path, 参数列表));
            }
            sb.AppendLine("    sld.TimeLine.MainSequence.ConvertToTextUnitEffect eff, " + 文本模式);



            sb.AppendLine("    Next");
            sb.AppendLine("End Sub");
            sb.AppendLine();
            return sb.ToString();
        }
    }
}
